﻿/****************************************************
	文件：EditorUtil.cs
	作者：HuskyT
	邮箱:  1005240602@qq.com
	日期：2019/09/07 23:22   	
	功能：编辑器常用工具API
*****************************************************/

using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

namespace HTUtility
{
    public class EditorUtil
    {
        #region Unity编辑器相关
        /// <summary>
        /// 复用菜单方法
        /// </summary>
        /// <param 菜单方法路径="menuItemPath"></param>
        public static void ReuseMenuItem(string menuItemPath)
        {
            EditorApplication.ExecuteMenuItem(menuItemPath);
        }
        /// <summary>
        /// 打开文件夹
        /// </summary>
        /// <param 文件夹路径="folderPath"></param>
        public static void OpenFolder(string folderPath)
        {
            Application.OpenURL("file:///" + folderPath);
        }
        /// <summary>
        /// 将指定资源导出成UnityPackage
        /// </summary>
        /// <param 待导出资源路径="assetPathName"></param>
        /// <param 导出文件的文件名="fileName"></param>
        public static void ExportUnityPackage(string assetPathName, string fileName)
        {
            EditorUtility.DisplayProgressBar("导出当前项目", string.Format("{0}正导出为UnityPackage", Application.productName), 0.1f);
            //递归导出指定文件夹下所有文件
            AssetDatabase.ExportPackage(assetPathName, fileName, ExportPackageOptions.Recurse);
            EditorUtility.DisplayProgressBar("导出当前项目", string.Format("{0}正导出为UnityPackage", Application.productName), 1f);
            EditorUtility.ClearProgressBar();
        }
        /// <summary>
        /// 生成UnityPackage名
        /// 默认：项目名_日期.unitypackage
        /// </summary>
        /// <returns></returns>
        public static string GenerateUnityPackageName(string packageName = null)
        {
            if (packageName == null)
            {
                string projectName = Application.productName;
                return projectName + "_" + DateTime.Now.ToString("yyyyMMdd_HH") + ".unitypackage";
            }
            else
            {
                return packageName + "_" + DateTime.Now.ToString("yyyyMMdd_HH") + ".unitypackage";
            }
        }
        /// <summary>
        /// 打开/运行指定文件
        /// </summary>
        /// <param 文件的完整路径，包括后缀="fileFullPath"></param>
        public static void OpenFile(string fileFullPath)
        {
            System.Diagnostics.Process.Start(fileFullPath);
        }
        /// <summary>
        /// 打开当前项目
        /// </summary>
        public static void OpenCurrentProject()
        {
            EditorApplication.OpenProject(Application.dataPath.Replace("Assets", string.Empty));
        }
        #endregion

        #region 提供脚本编译完成后的回调注册
        /// <summary>
        /// 存储回调字符串
        /// </summary>
        private static string mOnCompiledCallBackStr;
        /// <summary>
        /// 存储用的Key
        /// </summary>
        public const string SAVE_KEY_COMPILED_CALL_BACK = "SAVE_KEY_COMPILED_CALL_BACK";
        /// <summary>
        /// 注册脚本编译完成后的回调
        /// </summary>
        /// <param name="funcName">回调方法名</param>
        /// <param name="nameSpace">回调所在的命名空间</param>
        /// <param name="className">回调所在的类</param>
        public static void SubscribeCompileFinishedCallBack(string funcName, string nameSpace, string className)
        {
            string fullFuncStr = $"{nameSpace}.{className}.{funcName};";
            mOnCompiledCallBackStr = mOnCompiledCallBackStr + ";" + fullFuncStr;
            PlayerPrefs.SetString(SAVE_KEY_COMPILED_CALL_BACK, mOnCompiledCallBackStr);
        }
        /// <summary>
        /// 注销脚本编译完成后的回调
        /// </summary>
        /// <param name="funcName">回调方法名</param>
        /// <param name="nameSpace">回调所在的命名空间</param>
        /// <param name="className">回调所在的类</param>
        public static void UnsubscribeCompileFinishedCallBack(string funcName, string nameSpace, string className)
        {
            string fullFuncStr = $"{nameSpace}.{className}.{funcName};";
            mOnCompiledCallBackStr = mOnCompiledCallBackStr.Replace(fullFuncStr, string.Empty);
            PlayerPrefs.SetString(SAVE_KEY_COMPILED_CALL_BACK, mOnCompiledCallBackStr);
        }
        /// <summary>
        /// 注销所有脚本编译完成后的回调
        /// </summary>
        public static void UnsubscribeAllCompileFinishedCallBack()
        {
            mOnCompiledCallBackStr = string.Empty;
            PlayerPrefs.SetString(SAVE_KEY_COMPILED_CALL_BACK, mOnCompiledCallBackStr);
        }
        /// <summary>
        /// 脚本编译完成后调用该方法
        /// </summary>
        [UnityEditor.Callbacks.DidReloadScripts]
        private static void OnCompileFinished()
        {
            //解析方法：
            string allFuncStr = PlayerPrefs.GetString(SAVE_KEY_COMPILED_CALL_BACK, string.Empty);
            if (string.IsNullOrEmpty(allFuncStr)) return;
            string[] funcStrArray = allFuncStr.Split(';');
            if (funcStrArray.Length <= 0) return;
            foreach (string funcStr in funcStrArray)
            {
                if (string.IsNullOrEmpty(funcStr)) continue;
                string[] funcInfo = funcStr.Split('.');
                if (funcInfo.Length <= 0 || funcInfo.Length > 3) continue;
                string nameSpace = funcInfo[0];
                string className = funcInfo[1];
                string funcName = funcInfo[2];
                //反射调用
                object obj = HelperUtil.CreateClassObj($"{nameSpace}.{className}");
                HelperUtil.InvokeMethod(obj, funcName);
                Debug.LogFormat("编译完成后，反射调用：{0}", funcName);
            }
            UnsubscribeAllCompileFinishedCallBack();
        }
        /// <summary>
        /// 生成一个无用的CSharp脚本，用于启用编译后的回调
        /// </summary>
        public static void GenerateNoUseScript()
        {
            string folderPath = "Assets/Misc/CanDelete/";
            string scriptName = "NoUse.cs";
            HelperUtil.CheckOrCreateFolder(folderPath);
            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"//日期：{string.Concat(DateTime.Now.Year, "/", DateTime.Now.Month, "/", DateTime.Now.Day, " ", DateTime.Now.Hour, ":", DateTime.Now.Minute, ":", DateTime.Now.Second)}");
            //命名空间
            sb.AppendLine($"namespace {Consts.NAME_SPACE}");
            sb.AppendLine("{");
            //类名
            sb.AppendLine("\t[Serializable]");
            sb.AppendLine($"\tpublic class NoUse");
            sb.AppendLine("\t{");
            sb.AppendLine("\t}");
            sb.AppendLine("}");
            HelperUtil.WriteStringToFile(sb.ToString(), folderPath + scriptName, Encoding.UTF8);
        }
        #endregion
    }
}